home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / go / prog / sgf2mi13.taz / sgf2mi13 / statists.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-27  |  6.6 KB  |  314 lines

  1. /* #[info:            */
  2. /************************************************************************
  3.  *                                    *
  4.  *     #### #######    #    ####### ###  #### #######  ####        *
  5.  *    #        #      # #      #     #  #        #    #        *
  6.  *    #        #     #   #     #     #  #        #    #        *
  7.  *     ###     #    #######    #     #   ###     #     ###        *
  8.  *        #    #    #     #    #     #      #    #        #        *
  9.  *        #    #    #     #    #     #      #    #        #        *
  10.  *    ####     #    #     #    #    ### ####     #    ####        *
  11.  *                                    *
  12.  *                Jan van der Steen                *
  13.  *                                    *
  14.  *          Centre for Mathematics and Computer Science        *
  15.  *              Amsterdam, the Netherlands            *
  16.  *                                    *
  17.  *----------------------------------------------------------------------*
  18.  * File       : statists.c                         *
  19.  * Purpose : Emit statistics on the game                *
  20.  * Version : 1.3                            *
  21.  * Modified: 2/17/93 18:22:20                            *
  22.  * Author  : Jan van der Steen (jansteen@cwi.nl)             *
  23.  ************************************************************************/
  24. /* #]info:            */ 
  25. /* #[include:            */
  26.  
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include "gogame.h"
  31.  
  32. /* #]include:            */ 
  33. /* #[define:            */
  34.  
  35. #define MAXUSER        1024    /* Maximum length of username    */
  36. #define MAXKIBITZER    256    /* Maximum number of kibitzers    */
  37.  
  38. /* #]define:            */ 
  39. /* #[typedef:            */
  40.  
  41. typedef struct kib_info {
  42.     char *    kib_name;
  43.     int        kib_rank;
  44.     int        kib_n;
  45.     long    kib_tot;
  46.     int        kib_avrg;
  47. } KIBITZER;
  48.  
  49. /* #]typedef:            */ 
  50. /* #[extern:            */
  51.  
  52. extern    int     statout;    /* Emit the kibitz stats        */
  53.  
  54. /* #]extern:            */ 
  55. /* #[prototype:            */
  56.  
  57. #ifdef __STDC__
  58. #    define    PROTO(s) s
  59. #else
  60. #    define    PROTO(s) ()
  61. #endif
  62.  
  63. static    int    str2rank    PROTO((char *s));
  64. static    char *    rank2str    PROTO((int rank));
  65. static int    namesort    PROTO((KIBITZER *a, KIBITZER *b));
  66. static int    ranksort    PROTO((KIBITZER *a, KIBITZER *b));
  67. static int    freqsort    PROTO((KIBITZER *a, KIBITZER *b));
  68. static int    bytesort    PROTO((KIBITZER *a, KIBITZER *b));
  69. static int    avrgsort    PROTO((KIBITZER *a, KIBITZER *b));
  70.  
  71. #undef PROTO
  72.  
  73. /* #]prototype:            */ 
  74. /* #[static:            */
  75.  
  76. static    int        (*kibsort)()        = namesort;
  77. static    KIBITZER    kibitzers[MAXKIBITZER]    = {0};
  78.  
  79. /* #]static:            */ 
  80.  
  81. /* #[kib_list:            */
  82.  
  83. void
  84. kib_list(mode, label)
  85. /*
  86.  * List the kibitz info from the database
  87.  */
  88. int   mode;
  89. char *label;
  90. {
  91.     KIBITZER *k;
  92.     int          i;
  93.  
  94.     switch (mode) {
  95.     case 0:    kibsort = namesort; break;
  96.     case 1: kibsort = ranksort; break;
  97.     case 2: kibsort = freqsort; break;
  98.     case 3: kibsort = bytesort; break;
  99.     }
  100.     for (i = 0; i < MAXKIBITZER; i++) {
  101.     k = kibitzers+i;
  102.     if (k->kib_name) k->kib_avrg = (int)((k->kib_tot *100)/k->kib_n);
  103.     }
  104.     qsort(kibitzers, MAXKIBITZER, sizeof(KIBITZER), kibsort);
  105.  
  106.     for (i = 0; i < MAXKIBITZER; i++) {
  107.     k = kibitzers+i;
  108.     if (k->kib_name)
  109.         fprintf(stdout, "%s{%3d}{%-12s}{%-3s}{%3d}{%6ld}{%3d.%02d}\n",
  110.             label,
  111.             i+1,
  112.             k->kib_name,
  113.             rank2str(k->kib_rank),
  114.             k->kib_n,
  115.             k->kib_tot,
  116.             k->kib_avrg/100,
  117.             k->kib_avrg - 100*(k->kib_avrg/100));
  118.     }
  119. }
  120.  
  121. /* #]kib_list:            */ 
  122. /* #[kib_add:            */
  123.  
  124. void
  125. kib_add(text)
  126. /*
  127.  * Add kibitz info to the database
  128.  */
  129. TEXT *text;
  130. {
  131.     KIBITZER *k;
  132.     TEXT     *t;
  133.     int          i;
  134.  
  135.     for (t = text; t != (TEXT *) 0; t = t->cc_next) {
  136.     for (i = 0; i < MAXKIBITZER; i++) {
  137.         k = kibitzers+i;
  138.         if (!k->kib_name || !strcmp(k->kib_name, t->cc_name)) {
  139.         /*
  140.          * Either a free slot or we found the user
  141.          */
  142.         if (!k->kib_name) {
  143.             k->kib_name = t->cc_name;
  144.             k->kib_rank = str2rank(t->cc_rank);
  145.         }
  146.         k->kib_tot += strlen(t->cc_text);
  147.         k->kib_n++;
  148.         break;
  149.         }
  150.     }
  151.     if (strcmp(k->kib_name, t->cc_name))
  152.         fprintf(stderr,
  153.             "Internal error: User table full in kib_add()\n");
  154.     }
  155. }
  156.  
  157. /* #]kib_add:            */ 
  158.  
  159. /* #[namesort:            */
  160.  
  161. static int
  162. namesort(a, b)
  163. KIBITZER *a;
  164. KIBITZER *b;
  165. {
  166.     if (a->kib_name == (char *) 0) return  1000;
  167.     if (b->kib_name == (char *) 0) return -1000;
  168.  
  169.     return strcmp(a->kib_name, b->kib_name);
  170. }
  171.  
  172. /* #]namesort:            */ 
  173. /* #[ranksort:            */
  174.  
  175. static int
  176. ranksort(a, b)
  177. KIBITZER *a;
  178. KIBITZER *b;
  179. {
  180.     int cmp;
  181.  
  182.     if (a->kib_name == (char *) 0) return  1000;
  183.     if (b->kib_name == (char *) 0) return -1000;
  184.  
  185.     if ((cmp = a->kib_rank - b->kib_rank) != 0) return cmp;
  186.  
  187.     return namesort(a, b);
  188. }
  189.  
  190. /* #]ranksort:            */ 
  191. /* #[freqsort:            */
  192.  
  193. static int
  194. freqsort(a, b)
  195. KIBITZER *a;
  196. KIBITZER *b;
  197. {
  198.     int cmp;
  199.  
  200.     if (a->kib_name == (char *) 0) return  1000;
  201.     if (b->kib_name == (char *) 0) return -1000;
  202.  
  203.     if ((cmp =        b->kib_n   - a->kib_n   ) != 0) return cmp;
  204.     if ((cmp = (int) (b->kib_tot - a->kib_tot)) != 0) return cmp;
  205.  
  206.     return namesort(a, b);
  207. }
  208.  
  209. /* #]freqsort:            */ 
  210. /* #[bytesort:            */
  211.  
  212. static int
  213. bytesort(a, b)
  214. KIBITZER *a;
  215. KIBITZER *b;
  216. {
  217.     int cmp;
  218.  
  219.     if (a->kib_name == (char *) 0) return  1000;
  220.     if (b->kib_name == (char *) 0) return -1000;
  221.  
  222.     if ((cmp = (int) (b->kib_tot - a->kib_tot)) != 0) return cmp;
  223.     if ((cmp =        b->kib_n   - a->kib_n   ) != 0) return cmp;
  224.  
  225.     return namesort(a, b);
  226. }
  227.  
  228. /* #]bytesort:            */ 
  229. /* #[avrgsort:            */
  230.  
  231. static int
  232. avrgsort(a, b)
  233. KIBITZER *a;
  234. KIBITZER *b;
  235. {
  236.     int cmp;
  237.  
  238.     if (a->kib_name == (char *) 0) return  1000;
  239.     if (b->kib_name == (char *) 0) return -1000;
  240.  
  241.     if ((cmp =        b->kib_avrg - a->kib_avrg) != 0) return cmp;
  242.     if ((cmp = (int) (b->kib_tot  - a->kib_tot)) != 0) return cmp;
  243.     if ((cmp =        b->kib_n    - a->kib_n   ) != 0) return cmp;
  244.  
  245.     return namesort(a, b);
  246. }
  247.  
  248. /* #]avrgsort:            */ 
  249. /* #[str2rank:            */
  250.  
  251. static int
  252. str2rank(s)
  253. /*
  254.  * Parse and calculate a rank
  255.  * We distinguish several categories:
  256.  *
  257.  *    IGS92        IGS92     -100
  258.  *    professional    p      -10
  259.  *    dan        d       -1
  260.  *    kyu        k        1
  261.  *    NR        NR      100
  262.  *    ???        ???      101
  263.  */
  264. char *s;
  265. {
  266.     char *t = s;
  267.     int   factor = 0;
  268.     int   rank   = 0;
  269.  
  270.     if (!s || !*s) return -100;
  271.     s += strlen(s)-1;
  272.     if (*s == ' ' || *s == '*') s--;
  273.     switch (*s) {
  274.     case 'p': factor = -10; break;
  275.     case 'd': factor =  -1; break;
  276.     case 'k': factor =   1; break;
  277.     /*
  278.      * And now all "funny" rankings
  279.      */
  280.     case 'R': return  100;
  281.     case '?': return  101;
  282.     default : return -100;    /* We make them biggest so we notice them */
  283.     }
  284.  
  285.     /*
  286.      * When we arrive here we have to parse a {p,d,k} rank
  287.      */
  288.     while ('0' <= *t && *t <= '9') rank = 10*rank + (*t++ - '0');
  289.  
  290.     return factor * rank;
  291. }
  292.  
  293. /* #]str2rank:            */ 
  294. /* #[rank2str:            */
  295.  
  296. static char *
  297. rank2str(rank)
  298. int rank;
  299. {
  300.     static char s[10];
  301.  
  302.     if (rank ==  101)    return strcpy(s, " ??");
  303.     if (rank ==  100)    return strcpy(s, " NR");
  304.     if (rank == -100)    return strcpy(s, " XX");
  305.     if (rank <= -10 )    sprintf(s, "%2dp", -rank/10);
  306.     if (rank <= -1  )    sprintf(s, "%2dd", -rank);
  307.     if (rank >=  1  )    sprintf(s, "%2dk",  rank);
  308.  
  309.     return s;
  310. }
  311.  
  312. /* #]rank2str:            */ 
  313.  
  314.